/*
	Copyright (C) 2011 Salil Bhagurkar

	This file is part of illusion

	illusion is free software: you can redistribute it and/or modify
	it under the terms of the GNU Lesser General Public License as
	published by the Free Software Foundation, either version 3 of
	the License, or (at your option) any later version.

	illusion is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public
	License along with illusion. 
	If not, see <http://www.gnu.org/licenses/>.
*/

#include <arch/arch.h>
#include <arch/power.h>
#include <klib/lib.h>
#include <kernel/console.h>
#include <kernel/syscall.h>
#include <kernel/errors.h>
#include <kernel/init.h>
#include <kernel/sched.h>

/*
 * Kernel exception handlers tapped into the arch code
 * Fatal is true if the arch thinks this should not be used to recover
 * a user process for example.
 * For example, if a page fault is not handled and the page fault address
 * was located in the kernel (which is identified by an error code pushed
 * by the processor), then we should not attempt to recover.
 */
void handle_exception(uint_t code, char *msg, void *state, bool fatal)
{
	bool in_user;
	if(init_state == INIT_SYSTEM) {
		in_user = !(current_process->is_kernel);
	} else {
		in_user = false;
	}

	console_printf("Exception in %s mode%s: [%s]\n", in_user ? "user" : "kernel",
			in_syscall ? " inside system call" : "", msg);
	print_state(state);
	if(in_user && !fatal) {
		sys_exitprocess();
	} else {
		assertv(false, "Fatal\n");
	}
}
